This notebook explores the data model used for pointing radar data in the Python ARM Radar Toolkit (Py-ART). We will do this by loading a radar file from CF-Radial from ARM's X-Band system in the North Slope of Alaska Barrow site.
If you are not running this notebook in the short course VM, go fetch the data from HERE and place it in a data directory in the same directory as this notebook.
In [1]:
import pyart
from matplotlib import pyplot as plt
%matplotlib inline
filename = 'data/nsaxsaprrhiC1.a1.20131203.141936.nc'
Read the CF-Radial file into Py-ART's data model for pointing gated data
In [2]:
radar = pyart.io.read(filename)
Lets investigate what is at the top level with a dir() command
In [3]:
dir(radar)
Out[3]:
Anything in the data model which contains array-like data is a dictionary with metadata and the actual data contained in the 'data' key, for example the array which contains information about the elevation angle of the sensor.
In [4]:
radar.azimuth.keys()
Out[4]:
In [5]:
radar.azimuth['standard_name']
Out[5]:
In [6]:
radar.azimuth['data']
Out[6]:
In [7]:
f = plt.figure(figsize=[15,8])
plt.plot(radar.time['data'], radar.azimuth['data'] )
plt.xlabel(radar.time['standard_name'] + ' (' + radar.time['units'] + ')')
plt.ylabel(radar.azimuth['standard_name'] + ' (' + radar.azimuth['units'] + ')')
Out[7]:
So all the pointing data is contained in the base object, the azimuth and elevation of the antenna/sensor plus the range and time axes
In [8]:
print radar.range['data'].min(), radar.range['data'].max(), radar.range['units']
f = plt.figure(figsize=[15,8])
plt.plot(radar.time['data'], radar.elevation['data'] )
plt.xlabel(radar.time['standard_name'] + ' (' + radar.time['units'] + ')')
plt.ylabel(radar.elevation['standard_name'] + ' (' + radar.elevation['units'] + ')')
Out[8]:
there is also a swag of metadata contained within, well.. the metadata dictionary
In [9]:
for mykey in radar.metadata.keys():
print mykey, ': ', radar.metadata[mykey]
Now the final top level bit of information, the data model we use follows CF-Radial morphology and hence has a set of "helper" fields to format out the radar coverage pattern. That is, to seperate sweeps.
In [10]:
radar.sweep_end_ray_index['data']
f = plt.figure(figsize=[15,8])
for i in range(len(radar.sweep_end_ray_index['data'])):
start_index = radar.sweep_start_ray_index['data'][i]
end_index = radar.sweep_end_ray_index['data'][i]
plt.plot(radar.time['data'][start_index:end_index],
radar.elevation['data'][start_index:end_index],
label = 'Sweep number '+ str(radar.sweep_number['data'][i]))
plt.legend()
plt.xlabel(radar.time['standard_name'] + ' (' + radar.time['units'] + ')')
plt.ylabel(radar.elevation['standard_name'] + ' (' + radar.elevation['units'] + ')')
Out[10]:
Now to the actual data, or what ARM would call Primary Measurements. This is all stored in the field field of the radar object and is a dictionary of dictionaries. Best shown by example:
In [11]:
print radar.fields.keys()
print ""
for mykey in radar.fields.keys():
print mykey,':', radar.fields[mykey]['standard_name'] + ' (' + radar.fields[mykey]['units'] + ')'
As far as CF-Radial ingest and write is concerned the variable names correspond to the variable names, the non-array data to the variable attributes and the 'data' key to the array.. lets look at some data
In [12]:
f = plt.figure(figsize=[15,8])
my_pc = plt.pcolormesh(radar.range['data'], radar.time['data'],
radar.fields['reflectivity_horizontal']['data'])
plt.xlabel(radar.range['standard_name'] + ' (' + radar.range['units'] + ')')
plt.ylabel(radar.time['standard_name'] + ' (' + radar.time['units'] + ')')
cb = plt.colorbar(mappable = my_pc)
cb.set_label(radar.fields['reflectivity_horizontal']['standard_name'] +\
' (' + radar.fields['reflectivity_horizontal']['units'] + ')')
And of course we can use our sweep indicators to isolate a single sweep
In [13]:
f = plt.figure(figsize=[15,8])
start_index = radar.sweep_start_ray_index['data'][0]
end_index = radar.sweep_end_ray_index['data'][0]
my_pc = plt.pcolormesh(radar.range['data'], radar.time['data'][start_index:end_index],
radar.fields['reflectivity_horizontal']['data'][start_index:end_index, :])
plt.xlabel(radar.range['standard_name'] + ' (' + radar.range['units'] + ')')
plt.ylabel(radar.time['standard_name'] + ' (' + radar.time['units'] + ')')
cb = plt.colorbar(mappable = my_pc)
cb.set_label(radar.fields['reflectivity_horizontal']['standard_name'] +\
' (' + radar.fields['reflectivity_horizontal']['units'] + ')')
We can get a quick overview of what is contained in the radar object using the info method.
In [14]:
radar.info('compact') # see what happens with 'standard' or 'full'
This functionality is also available from the command line using the radar_info command.
In [15]:
!radar_info --compact data/nsaxsaprrhiC1.a1.20131203.141936.nc
Thus concludes the intro! Py-ART, of course, can do all this for you including pretty PPIs etc.. but this gives an introduction to the data model we use. Questions? Comments? Science Lead: Scott Collis Development lead: Jonathan Helmus.